package com.panfeng.xcloud.boss.provider.member.security.password;

import com.panfeng.xcloud.common.core.utils.MD5Utils;
import com.panfeng.xcloud.common.core.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

/**
 *
 * 自定义密码验证-登录验证提供者
 *
 * @author xiaobo
 * @version 1.0
 * @since 2018-12-28
 */
@Slf4j
public class PwdAuthenticationProvider implements AuthenticationProvider {

	private UserDetailsService userDetailsService;

	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		log.info(">>>> 开始执行PwdAuthenticationProvider鉴权提供者，查询认证用户信息 <<<");
		PwdAuthenticationToken authenticationToken = (PwdAuthenticationToken) authentication;
		//格式：grantType + "_" + accountNumber + "_" + password +"_"+ clientId +"_" + clientSecret
		String principal = (String) authenticationToken.getPrincipal();
		log.info(">>>> 执行PwdAuthenticationProvider鉴权提供者，principal信息：{} <<<",principal);
		UserDetails user = userDetailsService.loadUserByUsername(principal);
		if (user == null) {
			log.error(">>>> 执行PwdAuthenticationProvider鉴权提供者异常：无法获取用户信息 <<<");
			throw new InternalAuthenticationServiceException("无法获取用户信息");
		}
		String [] userAttachData = principal.split("\\_",5);
		String userPwd = StringUtils.isNotEmpty(userAttachData[2]) ? userAttachData[2] : "";
		String digestPwd = MD5Utils.digest(userPwd);
		if(StringUtils.isEmpty(digestPwd) || !digestPwd.equals(user.getPassword())){
			log.error(">>>> 执行PwdAuthenticationProvider鉴权提供者异常：密码输入不正确 <<<");
			throw new InternalAuthenticationServiceException("密码输入不正确");
		}
		//重新生成principal，由accountNumber转化成UserDetails
		PwdAuthenticationToken authenticationResult = new PwdAuthenticationToken(user,user.getAuthorities());
		authenticationResult.setDetails(authenticationToken.getDetails());
		return authenticationResult;
	}

	@Override
	public boolean supports(Class<?> authentication) {
		return PwdAuthenticationToken.class.isAssignableFrom(authentication);
	}

	public UserDetailsService getUserDetailsService() {
		return userDetailsService;
	}

	public void setUserDetailsService(UserDetailsService userDetailsService) {
		this.userDetailsService = userDetailsService;
	}

}
